package ms.jasim.framework.test;

import java.io.IOException;
import java.util.ArrayList;

import ms.jasim.model.Actor;
import ms.jasim.model.Capability;
import ms.jasim.model.DecomposeType;
import ms.jasim.model.Decomposition;
import ms.jasim.model.Dependency;
import ms.jasim.model.Goal;
import ms.jasim.model.GoalRequest;
import ms.jasim.model.JasimModel;
import ms.jasim.model.ModelFactory;
import ms.jasim.pddl.BrylPddlGenerator;
import ms.jasim.pddl.JasimOrgPddlGenerator;
import ms.jasim.pddl.PddlProblem;

import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.xmi.impl.XMIResourceImpl;

public class GenTestFilePattern2 {
	public final JasimModel model;
	private ArrayList<Goal> extPoints;
	
	public GenTestFilePattern2() {
		this.extPoints = new ArrayList<Goal>();
		model = ModelFactory.eINSTANCE.createJasimModel();
		createActors();
	}

	public void createActors() {
		Actor a[] = new Actor[7];
		for (int i = 1; i <= 6; i++) {
			a[i] = ModelFactory.eINSTANCE.createActor();
			a[i].setName("A" + i);
			model.getActors().getActor().add(a[i]);
		}
		createDependency(a[1], a[2], a[3]);
		createDependency(a[2], a[4], a[5]);
		createDependency(a[3], a[5], a[6]);
	}
	
	void createDependency(Actor source, Actor...actors) {
		for(Actor a: actors) {
			Dependency d = ModelFactory.eINSTANCE.createDependency();
			d.getTargetActor().add(a);
			source.getDependency().add(d);
		}
	}
	
	Decomposition createDecomposition(DecomposeType type, Goal...goals) {
		Decomposition de = ModelFactory.eINSTANCE.createDecomposition();
		de.setType(type);
		for (Goal g: goals)
			de.getSubGoals().add(g);
		return de;
	}
	
	void createCapability(Actor a, Goal...goals) {
		for (Goal g: goals) {
			Capability cap = ModelFactory.eINSTANCE.createCapability();
			cap.setGoal(g);
			a.getCapability().add(cap);
		}
	}
	
	public void createElementTree(String treeName) {
		Goal g[] = new Goal[16];
		for (int i = 1; i <= 15; i++) {
			g[i] = ModelFactory.eINSTANCE.createGoal();
			model.getGoals().getGoal().add(g[i]);
			g[i].setName(treeName + model.getGoals().size());
			if (i >= 11 && i <= 14)
				extPoints.add(g[i]);
		}
		g[1].getDecomposition().add(createDecomposition(DecomposeType.OR, g[2],g[3]));
		g[2].getDecomposition().add(createDecomposition(DecomposeType.AND, g[4],g[5], g[6]));
		g[3].getDecomposition().add(createDecomposition(DecomposeType.AND, g[7],g[8]));
		g[4].getDecomposition().add(createDecomposition(DecomposeType.OR, g[9],g[10]));
		g[5].getDecomposition().add(createDecomposition(DecomposeType.AND, g[11],g[12]));
		g[7].getDecomposition().add(createDecomposition(DecomposeType.AND, g[13],g[14], g[15]));
		
		createCapability(model.getActors().get(3), g[6], g[8], g[9], g[10], g[11], g[12]);
		createCapability(model.getActors().get(4), g[10], g[11], g[12], g[13], g[14], g[15]);	
		createCapability(model.getActors().get(5), g[13], g[14], g[15], g[6], g[8], g[9]);
		
		GoalRequest req = ModelFactory.eINSTANCE.createGoalRequest();
		req.setGoal(g[1]);
		model.getActors().get(0).getRequests().add(req);
	}

	public void increaseLevel() {
		ArrayList<Goal> clone = (ArrayList<Goal>) extPoints.clone();
		for (Goal g: clone) {
			Goal g1 = ModelFactory.eINSTANCE.createGoal();
			Goal g2 = ModelFactory.eINSTANCE.createGoal();
			model.getGoals().getGoal().add(g1);
			g1.setName("G" + model.getGoals().size());
			
			model.getGoals().getGoal().add(g2);
			g2.setName("G" + model.getGoals().size());
			
			g.getDecomposition().add(createDecomposition(DecomposeType.AND, g1, g2));
			extPoints.remove(g);
			extPoints.add(g1);
			// find actors  who provide goal g, remove the capability of providing goal g by 
			// two others of g1 and g2
			for (Actor a: model.getActors()) 
				for (Capability cap: a.getCapability()) 
					if (cap.getGoal() == g) {
						a.getCapability().remove(cap);
						createCapability(a, g1, g2);
						break;
					}
		}
	}
	
	public void save(String filename) throws IOException {
		String pddlFilename = filename +  ".pddl";
		String oldPddlFilename = filename +  ".bpddl";
		
		Resource resource = new XMIResourceImpl(URI.createURI(filename + ".jasim"));
        
		resource.getContents().add(model);

		try {
			resource.save(null);
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		System.out.println(filename);
		System.out.println("\tactors: " + model.getActors().size());
		System.out.println("\tgoals: " + model.getGoals().size());
		System.out.println("\tleaf goals: " + extPoints.size());
		
		PddlProblem pddlProblem = new JasimOrgPddlGenerator().getPddlProblem(model);
		pddlProblem.writeToFile(pddlFilename);
		
		System.out.println("\tJasim predicates: " + pddlProblem.facts.size());
		
		PddlProblem pddlProblem2 = new BrylPddlGenerator().getPddlProblem(model);
		pddlProblem2.writeToFile(oldPddlFilename);
		
		System.out.println("\tBryl predicates: " + pddlProblem2.facts.size());
	}
}

